/*
Language: HTML, XML
Website: https://www.w3.org/XML/
Category: common
*/

export default function (hljs) {
    var XML_IDENT_RE = '[A-Za-z0-9\\._:-]+';
    var XML_ENTITIES = {
        className: 'symbol',
        begin: '&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;'
    };
    var XML_META_KEYWORDS = {
        begin: '\\s',
        contains: [
            {
                className: 'meta-keyword',
                begin: '#?[a-z_][a-z1-9_-]+',
                illegal: '\\n'
            }
        ]
    };
    var XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
        begin: '\\(',
        end: '\\)'
    });
    var APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {
        className: 'meta-string'
    });
    var QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
        className: 'meta-string'
    });
    var TAG_INTERNALS = {
        endsWithParent: true,
        illegal: /</,
        relevance: 0,
        contains: [
            {
                className: 'attr',
                begin: XML_IDENT_RE,
                relevance: 0
            },
            {
                begin: /=\s*/,
                relevance: 0,
                contains: [
                    {
                        className: 'string',
                        endsParent: true,
                        variants: [
                            {
                                begin: /"/,
                                end: /"/,
                                contains: [XML_ENTITIES]
                            },
                            {
                                begin: /'/,
                                end: /'/,
                                contains: [XML_ENTITIES]
                            },
                            {
                                begin: /[^\s"'=<>`]+/
                            }
                        ]
                    }
                ]
            }
        ]
    };
    return {
        name: 'HTML, XML',
        aliases: ['html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist', 'wsf', 'svg'],
        case_insensitive: true,
        contains: [
            {
                className: 'meta',
                begin: '<![a-z]',
                end: '>',
                relevance: 10,
                contains: [
                    XML_META_KEYWORDS,
                    QUOTE_META_STRING_MODE,
                    APOS_META_STRING_MODE,
                    XML_META_PAR_KEYWORDS,
                    {
                        begin: '\\[',
                        end: '\\]',
                        contains: [
                            {
                                className: 'meta',
                                begin: '<![a-z]',
                                end: '>',
                                contains: [XML_META_KEYWORDS, XML_META_PAR_KEYWORDS, QUOTE_META_STRING_MODE, APOS_META_STRING_MODE]
                            }
                        ]
                    }
                ]
            },
            hljs.COMMENT('<!--', '-->', {
                relevance: 10
            }),
            {
                begin: '<\\!\\[CDATA\\[',
                end: '\\]\\]>',
                relevance: 10
            },
            XML_ENTITIES,
            {
                className: 'meta',
                begin: /<\?xml/,
                end: /\?>/,
                relevance: 10
            },
            {
                className: 'tag',
                /*
      The lookahead pattern (?=...) ensures that 'begin' only matches
      '<style' as a single word, followed by a whitespace or an
      ending braket. The '$' is needed for the lexeme to be recognized
      by hljs.subMode() that tests lexemes outside the stream.
      */
                begin: '<style(?=\\s|>)',
                end: '>',
                keywords: {
                    name: 'style'
                },
                contains: [TAG_INTERNALS],
                starts: {
                    end: '</style>',
                    returnEnd: true,
                    subLanguage: ['css', 'xml']
                }
            },
            {
                className: 'tag',
                // See the comment in the <style tag about the lookahead pattern
                begin: '<script(?=\\s|>)',
                end: '>',
                keywords: {
                    name: 'script'
                },
                contains: [TAG_INTERNALS],
                starts: {
                    end: '</script>',
                    returnEnd: true,
                    subLanguage: ['javascript', 'handlebars', 'xml']
                }
            },
            {
                className: 'tag',
                begin: '</?',
                end: '/?>',
                contains: [
                    {
                        className: 'name',
                        begin: /[^\/><\s]+/,
                        relevance: 0
                    },
                    TAG_INTERNALS
                ]
            }
        ]
    };
}
